package com.forestar.mapControl.utils.mapConvert.geometry.coordinatesystem;
/**
 * Created by liubo on 2017/7/5.
 */

import android.text.TextUtils;

import java.util.ArrayList;
import java.util.List;

public class CoordinateSystemRepository
  {
    public static final String CN_BJ54_3 = "北京54_3度分带";
    public static final String CN_BJ54_6 = "北京54_6度分带";
    public static final String CN_XIAN80_3 = "西安80_3度分带";
    public static final String CN_XIAN80_6 = "西安80_6度分带";
    public static final String CN_WGS84_3 = "WGS84_3度分带";
    public static final String CN_WGS84_6 = "WGS84_6度分带";
    public static final String CN_CGCS2000_3 = "国家2000_3度分带";
    public static final String CN_CGCS2000_6 = "国家2000_6度分带";
    public static final String CN_WITH_ZONECODE = "带(加带号)";
    public static final String CN_WITHOUT_ZONECODE = "带(不加带号)";

    public static final int ZONE3_START_CODE = 24;
    public static final int ZONE6_START_CODE = 12;
    public static final String WEB_MCT_NAME = "Web墨卡托投影";
    public static final String BEIJING54_NAME = "北京54经纬度";
    public static final String BEIJING54_BJLOCAL_NAME = "北京地方坐标系";
    public static final String XIAN80_NAME = "西安80经纬度";
    public static final String WGS84_NAME = "WGS84经纬度";
    public static final String CGCS2000_NAME = "国家2000经纬度";

    private final String UNKNOWN_COORDINATESYSTEM_NAME = "未知坐标系统";

    private static CoordinateSystemRepository coordSystemRepository;
    private List<EllipsoidBean> ellipsoidBeans = new ArrayList<>();

    public static CoordinateSystemRepository getInstance()
      {
        if (coordSystemRepository == null)
          {
            coordSystemRepository = new CoordinateSystemRepository();
          }
        return coordSystemRepository;
      }

    public String getSridName(int srid)
      {
        for (EllipsoidBean elb : ellipsoidBeans)
          {
            if (elb.isSridInclude(srid))
              {
                return elb.getSridName(srid);
              }
          }
        return UNKNOWN_COORDINATESYSTEM_NAME;
      }

    private CoordinateSystemRepository()
      {
        createCoordinateSystemInfo();
      }

    private void createCoordinateSystemInfo()
      {
        ellipsoidBeans = new ArrayList<>();
        // 54
        List<SridNameBean> sridNameBeans = new ArrayList<>();
        sridNameBeans.add(new SridNameBean(4214, BEIJING54_NAME));
        sridNameBeans.add(new SridNameBean(2400, 2422, CN_BJ54_3, CN_WITH_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(2421, 2443, CN_BJ54_3, CN_WITHOUT_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(21412, 21424, CN_BJ54_6, CN_WITH_ZONECODE, ZONE6_START_CODE));
        sridNameBeans.add(new SridNameBean(21452, 21464, CN_BJ54_6, CN_WITHOUT_ZONECODE, ZONE6_START_CODE));
        sridNameBeans.add(new SridNameBean(1000000, BEIJING54_BJLOCAL_NAME));
        ellipsoidBeans.add(new EllipsoidBean(BEIJING54_NAME, sridNameBeans));
        // 80
        sridNameBeans = new ArrayList<>();
        sridNameBeans.add(new SridNameBean(4610, XIAN80_NAME));
        sridNameBeans.add(new SridNameBean(2348, 2370, CN_XIAN80_3, CN_WITH_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(2369, 2391, CN_XIAN80_3, CN_WITHOUT_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(2326, 2338, CN_XIAN80_6, CN_WITH_ZONECODE, ZONE6_START_CODE));
        sridNameBeans.add(new SridNameBean(2337, 2349, CN_XIAN80_6, CN_WITHOUT_ZONECODE, ZONE6_START_CODE));
        ellipsoidBeans.add(new EllipsoidBean(XIAN80_NAME, sridNameBeans));
        // 2000
        sridNameBeans = new ArrayList<>();
        sridNameBeans.add(new SridNameBean(4490, CGCS2000_NAME));
        sridNameBeans.add(new SridNameBean(4512, 4534, CN_CGCS2000_3, CN_WITH_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(4533, 4555, CN_CGCS2000_3, CN_WITHOUT_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(4490, 4502, CN_CGCS2000_6, CN_WITH_ZONECODE, ZONE6_START_CODE));
        sridNameBeans.add(new SridNameBean(4501, 4513, CN_CGCS2000_6, CN_WITHOUT_ZONECODE, ZONE6_START_CODE));
        ellipsoidBeans.add(new EllipsoidBean(CGCS2000_NAME, sridNameBeans));
        //84
        sridNameBeans = new ArrayList<>();
        sridNameBeans.add(new SridNameBean(4326, WGS84_NAME));
        // 平面
        sridNameBeans.add(new SridNameBean(1000022, 1000044, CN_WGS84_3, CN_WITH_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(1000043, 1000065, CN_WGS84_3, CN_WITHOUT_ZONECODE, ZONE3_START_CODE));
        sridNameBeans.add(new SridNameBean(1000000, 1000012, CN_WGS84_6, CN_WITH_ZONECODE, ZONE6_START_CODE));
        sridNameBeans.add(new SridNameBean(1000011, 1000023, CN_WGS84_6, CN_WITHOUT_ZONECODE, ZONE6_START_CODE));
        // 墨卡托
        sridNameBeans.add(new SridNameBean(900913, WEB_MCT_NAME));
        sridNameBeans.add(new SridNameBean(3395, WEB_MCT_NAME));
        sridNameBeans.add(new SridNameBean(3857, WEB_MCT_NAME));
        sridNameBeans.add(new SridNameBean(102100, WEB_MCT_NAME));
        sridNameBeans.add(new SridNameBean(102113, WEB_MCT_NAME));
        sridNameBeans.add(new SridNameBean(54004, WEB_MCT_NAME));
        ellipsoidBeans.add(new EllipsoidBean(WGS84_NAME, sridNameBeans));
      }

    public static CoordinateParameterBean CoordinateParameterToSelectBean(String formula)
      {
        ArrayList<CoordinateParameterBean> beans = CoordinateParameterToBean(formula);
        for (CoordinateParameterBean bean : beans)
          {
            if (bean.isSelect())
              {
                return bean;
              }
          }
        return null;
      }

    public List<EllipsoidBean> getEllipsoidBeans()
      {
        return this.ellipsoidBeans;
      }

    // TODO liubo 2017年7月5日16:42:45 五参数在加载到内存时要取反
    public static ArrayList<CoordinateParameterBean> CoordinateParameterToBean(String formula)
      {
        ArrayList<CoordinateParameterBean> beans = new ArrayList<CoordinateParameterBean>();
        if (formula.isEmpty())
          {
            return beans;
          }
        String[] coordinateString = formula.split(";");
        for (int i = 0; i < coordinateString.length - 1; i++)
          {
            String[] beanString = coordinateString[i].split(",");
            CoordinateParameterBean bean = new CoordinateParameterBean();
            bean.setName(beanString[0]);
            bean.setDx(Double.parseDouble(beanString[1]));
            bean.setDy(Double.parseDouble(beanString[2]));
            bean.setDz(Double.parseDouble(beanString[3]));
            beans.add(bean);
          }
        if (Integer.parseInt(coordinateString[coordinateString.length - 1]) != -1)
          {
            beans.get(Integer.parseInt(coordinateString[coordinateString.length - 1])).setSelect(true);
          }
        return beans;
      }

    public static String CoordinateParameterToString(ArrayList<CoordinateParameterBean> beans)
      {
        StringBuffer formula = new StringBuffer();
        if (beans.size() == 0)
          {
            return "";
          }
        int select = -1;
        for (int i = 0; i < beans.size(); i++)
          {
            CoordinateParameterBean bean = beans.get(i);
            formula.append(bean.getName()).append(",").append(bean.getDx()).append(",").append(bean.getDy()).append(",").append(bean.getDz()).append(";");
            if (bean.isSelect())
              {
                select = i;
              }
          }
        formula.append(select);
        return formula.toString();
      }

    public class EllipsoidBean
      {
        private final String ellipsoidName;
        private List<SridNameBean> sridNameBeans;

        public EllipsoidBean(String ellipsoidName, List<SridNameBean> sridNameBeans)
          {
            this.ellipsoidName = ellipsoidName;
            this.sridNameBeans = sridNameBeans;
          }

        public String getName()
          {
            return ellipsoidName;
          }

        public boolean isSridInclude(int srid)
          {
            for (SridNameBean bean : sridNameBeans)
              {
                if (bean.match(srid))
                  {
                    return true;
                  }
              }
            return false;
          }

        public String getSridName(int srid)
          {
            for (SridNameBean bean : sridNameBeans)
              {
                if (bean.match(srid))
                  {
                    return bean.getName(srid);
                  }
              }
            return UNKNOWN_COORDINATESYSTEM_NAME;
          }

        public List<SridNameBean> getSridNameBeans()
          {
            return this.sridNameBeans;
          }
      }

    public class SridNameBean
      {
        // 以下变量为一组分带坐标系统服务
        public int sridBegin;
        public int sridEnd;
        public String namePrefix;   // 例如  CN_BJ54_3
        public String nameSuffix;   // 例如  CN_WITH_ZONECODE
        public int zoneCodeStartOffset;

        // 以下变量为单个坐标系统服务
        private int singleSrid = -1;
        private String singleCoordName;

        public SridNameBean(int sridBegin, int sridEnd, String namePrefix, String nameSuffix, int zoneCodeStartOffset)
          {
            this.sridBegin = sridBegin;
            this.sridEnd = sridEnd;
            this.namePrefix = namePrefix;
            this.nameSuffix = nameSuffix;
            this.zoneCodeStartOffset = zoneCodeStartOffset;
          }

        public SridNameBean(int srid, String coordName)
          {
            this.singleSrid = srid;
            this.singleCoordName = coordName;
          }

        public String getSingleCoordName()
          {
            return singleCoordName;
          }

        public int getSingleSrid()
          {
            return singleSrid;
          }

        public boolean match(int srid)
          {
            return (srid == this.singleSrid || (srid > sridBegin && srid < sridEnd));
          }

        public String getName(int srid)
          {
            // 地理坐标系
            if (!TextUtils.isEmpty(singleCoordName))
              {
                return singleCoordName;
              }
            // 分带坐标系
            if (srid > sridBegin || sridBegin < sridEnd)
              {
                return namePrefix + String.valueOf(srid - sridBegin + zoneCodeStartOffset) + nameSuffix;
              }
            return UNKNOWN_COORDINATESYSTEM_NAME;
          }
      }

  }

